home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 127_01.zip / RAP3.C < prev    next >
Text File  |  1993-06-17  |  14KB  |  553 lines

  1. /*********************************************************************\
  2. ** .---------------------------------------------------------------. **
  3. ** |                                                               | **
  4. ** |                                                               | **
  5. ** |         Copyright (c) 1981, 1982, 1983 by Eric Martz.         | **
  6. ** |                                                               | **
  7. ** |                                                               | **
  8. ** |       Permission is hereby granted to use this source         | **
  9. ** |       code only for non-profit purposes. Publication of       | **
  10. ** |       all or any part of this source code, as well as         | **
  11. ** |       use for business purposes is forbidden without          | **
  12. ** |       written permission of the author and copyright          | **
  13. ** |       holder:                                                 | **
  14. ** |                                                               | **
  15. ** |                          Eric Martz                           | **
  16. ** |                         POWER  TOOLS                          | **
  17. ** |                    48 Hunter's Hill Circle                    | **
  18. ** |                      Amherst MA 01002 USA                     | **
  19. ** |                                                               | **
  20. ** |                                                               | **
  21. ** `---------------------------------------------------------------' **
  22. \*********************************************************************/
  23.  
  24. #include "rap.h"
  25.  
  26. /*-------------------------------------------------------------------------*/
  27. getwrd(next)
  28.  
  29. /* STARTING AT THE POINTER *next, FINDS THE NEXT WORD AND SETS THE POINTERS
  30. Wordbegin AND Wordend, MOVING *next TO THE CHARACTER AFTER Wordend. Wordlen
  31. IS CALCULATED TAKING INTO ACCOUNT IMBEDDED POST_SS COMMANDS OR BACKSPACES.
  32. RETURNS Wordlen WHICH IS ZERO IF LAST WORD WAS GOTTEN ON PREVIOUS CALL. IF
  33. AN OPENING POST_SS_DELIMITER IS FOUND IN THE WORD, THE WORD MUST NOT END
  34. UNTIL A CLOSING DELIMITER IS FOUND, TO PREVENT BREAKING A LINE WITHIN AN
  35. ORIGINAL STRING TO BE POST-SUBSTITUTED. */
  36.  
  37.     char **next;
  38.     {
  39.     char *p1, *p2;
  40.     int even_delim;
  41.     if (**next EQ NULL) return(0);
  42.     even_delim = YES;
  43.  
  44.     /* FIND WORD */
  45.     if (Post_ss) {
  46.         for(p1 = *next;
  47.             ((*p1 NE NULL) AND
  48.             ((even_delim EQ NO) OR
  49.             (*p1 NE SPACE AND *p1 NE TAB AND *p1 NE DASH)))
  50.             ;p1++) {
  51.                 if(*p1 EQ Post_ss_delim) {
  52.                     if (even_delim) even_delim = NO;
  53.                     else even_delim = YES;
  54.                 }
  55.         }
  56.     }
  57.     else {
  58.         for(p1 = *next;
  59.             ((*p1 NE NULL) AND
  60.             (*p1 NE SPACE AND *p1 NE TAB AND *p1 NE DASH))
  61.             ;p1++)
  62.                 ;
  63.     }
  64.     
  65.  
  66.     if ((*p1 EQ NULL) AND (even_delim EQ NO)) {
  67.         fprintf(STDERR,
  68.             "Fatal error in line %d:\n%s%s",
  69.             In_linecnt,
  70.             "opening post-formatting string substitution delimiter\n",
  71.             "without closing delimiter.\n");
  72.         exit(0);
  73.     }
  74.  
  75.     /* ALLOW BREAK AT DASH BUT INCLUDE DASH IN WORD */
  76.     if (*p1 EQ DASH) p1++;
  77.  
  78.     /* SET EXTERNALS */
  79.     Wordbegin = *next;
  80.     Wordend = p1 - 1;
  81.     Wordlen = p1 - *next;
  82.     *next = p1;
  83.  
  84.     /* Wordlen CORRECTION ROUTINE */
  85.     for (p1 = Wordbegin; p1 <= Wordend; p1++) {
  86.         if (Post_ss AND *p1 EQ Post_ss_delim) {
  87.             /* IF NO CHARACTERS BETWEEN COMMAND DELIMITERS, LEAVE FOR
  88.             LATER SUBSTITUTION OF A SINGLE COMMAND DELIMITER TO BE
  89.             PRINTED. */
  90.             if (*p1+1 EQ Post_ss_delim) {
  91.                 Wordlen -= 1;
  92.                 p1++; /* IGNORE SECOND COMMAND DELIMITER IN THE PRESENT
  93.                     FOR LOOP */
  94.                 continue;
  95.             }
  96.             else {
  97.  
  98.                 /* FIND CLOSING DELIMITER */
  99.                 for (p2 = p1+1; *p2 NE Post_ss_delim; p2++)
  100.                     ;
  101.                 
  102.                 /* CORRECT Wordlen */
  103.                 Wordlen -= (p2 - p1 + 1);
  104.  
  105.                 /* CONTINUE SCANNING AFTER THE TERMINAL DELIMITER */
  106.                 p1 = p2; /* for loop will now p1++ */
  107.             }
  108.         }
  109.         else if (*p1 EQ BACKSPACE) Wordlen -= 2;
  110.     }
  111. #ifdef DEBUG
  112.     if (Debug) {
  113.         fprintf(STDERR,"Getwrd: \"");
  114.         for (p1 = Wordbegin; p1 <= Wordend; p1++) putc(*p1,STDERR);
  115.         fprintf(STDERR,"\" (Wordlen = %d)\n",Wordlen);
  116.     }
  117. #endif
  118.     return(1);
  119. }
  120.  
  121. /*-------------------------------------------------------------------------*/
  122. getspaces(next)
  123.  
  124. /* DETERMINES THE VALUE OF Spacecnt, WHICH IS THE NUMBER OF SPACES WHICH
  125. SHOULD SEPARATE THE PREVIOUS WORD FROM THE NEXT WORD. NOTE THAT EXPANSION OF
  126. NON-LEADING TABS IS NOT APPLICABLE WHEN FILLING, i. e. IN THIS FUNCTION */
  127.  
  128.     char **next;
  129.     {
  130.     Spacecnt = 0;
  131.     while (**next EQ SPACE OR
  132.             **next EQ TAB OR
  133.             **next EQ NULL) {
  134.         Spacecnt++; /* formerly Spacecnt=1 */
  135.         if (**next NE NULL) (*next)++;
  136.         else break;
  137.     }
  138. /*
  139.     /* PUT 2 SPACES AFTER PERIOD ENDING SENTENCE IF
  140.         1. NEXT WORD IS CAPITALIZED
  141.         2. PRECEDING WORD IS LONGER THAN 2 LETTERS (FOR INITIALS, Wm., Dr.)
  142.     */
  143.     if (*Wordend EQ '.' AND (Wordlen > 3)
  144.     AND Spacecnt AND (isupper(**next)))
  145.         Spacecnt = 2;
  146. */
  147.     /* IF THE PREVIOUS WORD ENDS IN A DASH AT THE END OF THE LINE, THEN WE
  148.     ARE IN THE MIDDLE OF A HYPHENATED WORD AND NO SPACES SHOULD FOLLOW THE
  149.     DASH. */
  150.  
  151.     if (*Wordend EQ DASH
  152.         AND ((*next - Wordend) EQ 1)
  153.         AND (**next EQ NULL)) Spacecnt = 0;
  154. #ifdef DEBUG
  155.     if (Debug) fprintf(STDERR,"Getspaces: Spacecnt = %d\n",Spacecnt);
  156. #endif
  157. }
  158.  
  159. /*-------------------------------------------------------------------------*/
  160. putwrd() {
  161.     int newlen, line_len, indelim;
  162.     char *p1;
  163. #ifdef DEBUG
  164.     if (Debug) fprintf(STDERR,"putwrd(entry)");
  165. #endif
  166.     line_len = Rmval - Tival;
  167.     newlen = Outlen + Wordlen + Spacecnt;
  168.     if (newlen > line_len) {
  169.         if (!Sanders AND Justify) {
  170.             spread (Outbuf, line_len - Outlen + 1, Outwrds);
  171.         }
  172.         if (Sanders AND Justify) brk(FORCEPRINT);
  173.         else brk(CR);
  174.     }
  175.     if (Wordlen) Outwrds++;
  176.     for (p1 = Wordbegin; p1 <= Wordend; p1++) {
  177. #ifdef DEBUG
  178.         if (Debug) putc(*p1,STDERR);
  179. #endif
  180.         *(Nextout++) = *p1;
  181.     }
  182.     if (Spacecnt < 0 OR Wordlen < 0) {
  183.         fprintf(STDERR,
  184.             "Wordlen=%d, Spacecnt=%d, EXIT IN getwrd()\n",
  185.             Wordlen,Spacecnt);
  186.         exit(0);
  187.     }
  188.     fillbuf(&Nextout, SPACE, Spacecnt);
  189.     Outlen += Wordlen + Spacecnt;
  190. #ifdef DEBUG
  191.     if (Debug) fprintf(STDERR,
  192.         "(return)Outwrds=%d  Outlen=%d\n",Outwrds,Outlen);
  193. #endif
  194. }
  195. /*-------------------------------------------------------------------------*/
  196. fillbuf(next, c, cnt)
  197.     char c, **next;
  198.     int cnt;
  199.     {
  200.     while (cnt--) {
  201.         **next = c;
  202.         *next += 1;
  203.     }
  204. }
  205. /*-------------------------------------------------------------------------*/
  206. fillulbuf(textline)
  207.     char *textline;
  208.     {
  209.     int indelim;
  210.     char *p, *nextul, *pflip;
  211. #ifdef DEBUG
  212.     if (Debug) fprintf(STDERR,"Fillulbuf\n");
  213. #endif
  214.     pflip = getflip('U', Ul_plus, textline);
  215.     if (!pflip) {
  216.         *Ulbuf = NULL;
  217.         return(0);
  218.     }
  219.     nextul = Ulbuf;
  220.     indelim = NO;
  221.     for(p = textline; *p; p++) {
  222.         /* SET Ul_plus */
  223.         if (p EQ pflip) {
  224.             Ul_plus? Ul_plus=NO: Ul_plus=YES;
  225.             pflip = getflip('U', Ul_plus, pflip+1);
  226.         }
  227.         /* SKIP POST SUBSTITUTIONS */
  228.         if (Post_ss AND *p EQ Post_ss_delim) {
  229.             if (indelim) {
  230.                 indelim = NO;
  231.                 continue;
  232.             }
  233.             else indelim = YES;
  234.         }
  235.         if (indelim) continue;
  236.         
  237.         if (*p EQ BACKSPACE) {
  238.             nextul--;
  239.             continue;
  240.         }
  241.         if (Ul_plus AND (isalpha(*p) OR isdigit(*p)))
  242.             *nextul++ = '_';
  243.         else *nextul++ = SPACE;
  244.     }
  245.     *nextul = NULL;
  246. }
  247. /*-------------------------------------------------------------------------*/
  248. boldonly(textline)
  249.     char *textline;
  250.     {
  251.     int indelim;
  252.     char *p, *nextul, *pflip;
  253. #ifdef DEBUG
  254.     if (Debug) fprintf(STDERR,"BOLDONLY\n");
  255. #endif
  256.     pflip = getflip('B', Bo_plus, textline);
  257.     if (!pflip) return(NO);
  258.     indelim = NO;
  259.     for(p = textline; *p; p++) {
  260.         /* SET Bo_plus */
  261.         if (p EQ pflip) {
  262.             Bo_plus? Bo_plus=NO: Bo_plus=YES;
  263.             pflip = getflip('B', Bo_plus, pflip+1);
  264.         }
  265.         /* SKIP POST SUBSTITUTIONS */
  266.         if (Post_ss AND *p EQ Post_ss_delim) {
  267.             if (indelim) {
  268.                 indelim = NO;
  269.                 continue;
  270.             }
  271.             else indelim = YES;
  272.         }
  273.         if (indelim OR
  274.             (*p EQ BACKSPACE) OR
  275.             Bo_plus
  276.             ) continue;
  277.         else *p = SPACE;
  278.     }
  279.     return(YES);
  280. }
  281. /*-------------------------------------------------------------------------*/
  282. getflip(type, status, previous)
  283.     char type, *previous;
  284.     int status;
  285.     {
  286.     char flip[16];
  287.     char b1[5], b2[5], u1[5], u2[5];
  288.     makebu(b1, b2, u1, u2);
  289.     if (type EQ 'U') { /* UNDERLINE */
  290.         if (status) strcpy(flip, u2);
  291.         else strcpy(flip, u1);
  292.     }
  293.     else { /* BOLDFACE */
  294.         if (status) strcpy(flip, b2);
  295.         else strcpy(flip, b1);
  296.     }
  297.     return(instrp(previous, flip));
  298. }
  299. /*-------------------------------------------------------------------------*/
  300. instrp(start, tofind)
  301.  
  302. /* IN-STRING-POINTER: LOOKS FOR tofind BEGINNING AT start.
  303.     RETURNS POINTER TO BEGINNING OF FIRST INSTANCE OF tofind,
  304.     OR 0 IF NOT FOUND. */
  305.  
  306.     char *start, *tofind;
  307.     {
  308.     char *ptr;
  309.     int len;
  310.     len = strlen(tofind);
  311.     for (ptr=start; *ptr; ptr++)
  312.         if (lefteq(ptr, tofind) EQ len) return(ptr);
  313.     return (0);
  314. }
  315. /*-------------------------------------------------------------------------*/
  316. putline(line, eol)
  317.     char *line, eol;
  318.     {
  319.     char delim_str[2];
  320.     if (Print_at) goto done;
  321.     delim_str[0] = Post_ss_delim;
  322.     delim_str[1] = NULL;
  323. #ifdef DEBUG
  324.     if (Debug) fprintf(STDERR,"Putline\n");
  325. #endif
  326.     /* SAVE LINE BEFORE POST SS */
  327.     strcpy(Ulbuf, line);
  328.  
  329.     /* POST SS AND PRINT */
  330.     if (Post_ss) ss(line, delim_str);
  331.     screen_status();
  332.     if (Ce_input AND *Center_mode)
  333.         puts(Center_mode);
  334.     else indent (Tival);
  335.     puts(line);
  336.  
  337.     /* BOLDFACE */
  338.     if (!(*Bo_on)) {
  339.         strcpy(line, Ulbuf);
  340.         if (boldonly(line)) {
  341.             if (Post_ss) ss(line, delim_str);
  342.             putchar(CR);
  343.             puts(Bo_shift);
  344.             indent(Tival);
  345.             puts(line);
  346.             puts(Bo_restore);
  347.         }
  348.     }
  349.     
  350.     /* UNDERLINE */
  351.     if (!(*Ul_on)) {
  352.         strcpy(line, Ulbuf);
  353.         fillulbuf(line);
  354.         if (*Ulbuf) {
  355.             putchar(CR);
  356.             puts(Ul_shift);
  357.             indent(Tival);
  358.             puts(Ulbuf);
  359.             puts(Ul_restore);
  360.         }
  361.     }
  362.     if (eol EQ CR OR !Forceprint) putchar(NEWLINE);
  363.     /* i.e. IF EOL NE FORCEPRINT */
  364.     /* N. B. putchar EXPANDS NEWLINE TO CR-NEWLINE! */
  365.     else puts(Forceprint);
  366.     if (Ce_input AND *Center_mode) restore_mode();
  367. done:
  368.     Tival = Inval;
  369. }
  370. /*-------------------------------------------------------------------------*/
  371.  
  372. brk(eol)
  373.     char eol;
  374.     {
  375. #ifdef DEBUG
  376.     if (Debug) fprintf(STDERR,"Brk\n");
  377. #endif
  378.     *Nextout = NULL;
  379.     /* TRIM OFF TRAILING BLANKS */
  380.     while (*(Nextout - 1) EQ SPACE AND Nextout > Outbuf) {
  381.         Nextout--;
  382.         *Nextout = NULL;
  383.     }
  384.     if (Outbuf[0]) put (Outbuf,eol);
  385.     Outwrds = 0;
  386.     Outlen = 0;
  387.     Nextout = Outbuf;
  388. }
  389. /*------------------------------------------------------------------------*/
  390.  
  391. anotherline(bf)
  392.  
  393. /* GETS ONE LINE FROM INPUT FILE AND PERFORMS PRE_SS. IF PRE_SS RESULTS IN
  394. BREAKING THE INPUT LINE INTO MULTIPLE LINES, THE EXTRA LINES ARE STORED IN
  395. Extralines AND HANDED OUT ONE AT A TIME. */
  396.  
  397.     char *bf;
  398.     {
  399.     char delim_str[2], discard[BIGBUF];
  400.     char b1[5], b2[5], u1[5], u2[5];
  401.     int i;
  402.  
  403.     delim_str[0] = Pre_ss_delim;
  404.     delim_str[1] = NULL;
  405.     if (Extrafull) {
  406.         strcpy(bf, Extralines);
  407.         saveextra(bf);
  408.     }
  409.     else {
  410. again:
  411.         if ((rapgets(bf, Fpin)) EQ 0) return(0);
  412.         /* RAPGETS IS FNNGETS WITH SETTING OF Press_flg + FOR \\(EVEN),
  413.         - FOR \(ODD) AND ZERO FOR NONE */
  414. /*        
  415.         if (New_portion) {
  416.             if ((i=instr(0,bf,PORTIT_O)) NE ERROR) {
  417.                 strcpy(discard,bf);
  418.                 while((instr(0,discard,PORTIT_C)) EQ ERROR)
  419.                     if (!rapgets(discard, Fpin)) return(0);
  420.                 bf[i] = NULL;
  421.                 Fpin = Fp_main;
  422.                 i = In_linecnt;
  423.                 In_linecnt = In_main;
  424.                 In_main = i;
  425.                 Old_portion = New_portion;
  426.                 New_portion = 0;
  427.                 /* if blank line, dont feed thru since will break fill */
  428.                 if (!(*bf)) goto again;
  429.             }
  430.         }
  431. */
  432. #ifdef DEBUG
  433.         if (Debug) fprintf(STDERR,
  434.             "\nAnotherline reads input line %d\n",In_linecnt);
  435. #endif
  436.         /* IF AN INCOMPLETE PRE_SS IS FOUND, CONCATENATE ANOTHER LINE */
  437.         if (Pre_ss AND Press_flg < 0) {
  438.             if ((rapgets(Extralines, Fpin)) EQ 0) {
  439.                 fprintf(STDERR,
  440.                 "Odd number of pre-format substitution delimiters\n%s",
  441.                 "in last line of input file.\n");
  442.                 return(1);
  443.             }
  444.             if (Press_flg >= 0) {
  445.                 fprintf(STDERR,
  446.                 "Incomplete pre-format substitution string in line %d\n",
  447.                     In_linecnt-1);
  448.                 fprintf(STDERR,
  449.                     "not completed in line %d.\n",
  450.                     In_linecnt);
  451.                 exit(0);
  452.             }
  453.             strcat(bf," ");
  454.             strcat(bf, Extralines);
  455.             Press_flg = 1;
  456.         }
  457.         if (Pre_ss AND
  458.             (Press_flg OR Press_all) AND
  459.             (lefteq(bf, ".he") NE 3) AND
  460.             (lefteq(bf, ".fo") NE 3)
  461.             ) {
  462.             ss(bf, delim_str);
  463.             saveextra(bf);
  464.         }
  465.         if (Exp_ctrl_chars) expand_controls(bf);
  466.  
  467.         /* COMMAND TEXT LINES (TAB CONT OR INDEX) MUST USE }b+}/}u+} */
  468.         if (*Inbuf EQ COMMAND) return(1);
  469.  
  470.         /* UNDERLINING */
  471.         makebu(b1, b2, u1, u2);
  472.         if (Ul_input) {
  473.             for(i=0; isspace(bf[i]); i++)
  474.                 discard[i] = bf[i];
  475.             discard[i] = NULL;
  476.             strcat(discard, u1);
  477.             strcat(discard,bf+i);
  478.             strcpy(bf,discard);
  479.             strcat(bf, u2);
  480.         }
  481.         /* BOLDFACE */
  482.         if (Bo_input) {
  483.             for(i=0; isspace(bf[i]); i++)
  484.                 discard[i] = bf[i];
  485.             discard[i] = NULL;
  486.             strcat(discard, b1);
  487.             strcat(discard,bf+i);
  488.             strcpy(bf,discard);
  489.             strcat(bf, b2);
  490.         }
  491.         return(1);
  492.     }
  493. }
  494. /*------------------------------------------------------------------------*/
  495. makebu(b1, b2, u1, u2)
  496.     char *b1, *b2, *u1, *u2;
  497.     {
  498.     b1[0] = b2[0] = u1[0] = u2[0] = Post_ss_delim;
  499.     b1[3] = b2[3] = u1[3] = u2[3] = Post_ss_delim;
  500.     b1[4] = b2[4] = u1[4] = u2[4] = NULL;
  501.     b1[1] = b2[1] = 'b';
  502.     u1[1] = u2[1] = 'u';
  503.     b1[2] = u1[2] = '+';
  504.     b2[2] = u2[2] = '-';
  505. }
  506. /*------------------------------------------------------------------------*/
  507. saveextra(next)
  508.     char *next;
  509.     {
  510.     Extrafull = NO;
  511.     for (; *next; next++) {
  512.         if ((*next EQ CR) AND (*(next+1) EQ NEWLINE)) {
  513.             *next = NULL;
  514.             if (*(next+2)) {
  515.                 strcpy (Extralines, next+2);
  516.                 Extrafull = YES;
  517.             }
  518.             break;
  519.         }
  520.     }
  521. }
  522. /*------------------------------------------------------------------------*/
  523. expand_controls(buf)
  524.     char *buf;
  525.     {
  526.     char tmp[512], *p;
  527.     int i;
  528.     i = 0;
  529.     p = buf;
  530.     while(*p) {
  531.         if (*p >= SPACE OR *p EQ TAB OR *p EQ BACKSPACE OR *p EQ FORMFEED) {
  532.             if (*p NE '\177' /* DEL */) tmp[i++] = *(p++);
  533.             else {
  534.                 tmp[i++] = '^';
  535.                 tmp[i++] = '?';
  536.                 p++;
  537.             }
  538.         }
  539.         else {
  540.             tmp[i++] = '^';
  541.             tmp[i++] = (*p + '@');
  542.             p++;
  543.         }
  544.     }
  545.     tmp[i] = NULL;
  546.     strcpy(buf, tmp);
  547. }
  548.  
  549. /*------------------------------------------------------------------------*/
  550. /* END OF RAP3.C */
  551. 
  552.     b1[1] = b2[1] = 'b';
  553.     u1[1] = u